﻿using Qy.Common;
using Qy.Models;
using Qy.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Qy.Service
{
    [AppService]
    public class UserDeptService
    {
        private readonly UserDeptRepository _adminUserDept;
        private readonly UserRepository _adminUser;
        private readonly ICacheManager _cacheManager;
        private readonly string cacheKey;
        public UserDeptService(ICacheManager cacheManager, UserDeptRepository adminUserDeptRepository, UserRepository adminUser)
        {
            _adminUserDept = adminUserDeptRepository;
            _cacheManager = cacheManager;
            cacheKey = CacheConst.CACHE_KEY_ADMINDEPTCATE;
            _adminUser = adminUser;
        }

        /// <summary>
        /// 全部列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<UserDept>> GetAllAsync()
        {
            List<UserDept> cate = _cacheManager.Get<List<UserDept>>(cacheKey);
            if (cate == null)
            {
                cate = await _adminUserDept.GetAllListAsync("Id desc");
                _cacheManager.Set(cacheKey, cate, TimeSpan.FromDays(10));
            }
            return cate;
        }

        public async Task<UserDept> GetInfo(int id)
        {
            List<UserDept> userDepts = await GetAllAsync();
            return userDepts.FirstOrDefault(a => a.Id == id);
        }


        #region 获取所有下级

        /// <summary>
        /// 获取当前部门及子部门ID值字符串
        /// </summary>
        /// <param name="Pid"></param>
        /// <returns></returns>
        public async Task<List<int>> GetDeptAndSonIdsAsync(int Pid)
        {
            List<UserDept> userDepts = await GetAllAsync();
            var query = userDepts.Where(p => p.Id == Pid).ToList();
            var list2 = query.Concat(GetSonList(userDepts, Pid));
            List<int> ids = list2.Select(o => o.Id).ToList();
            //ids.Add(Pid);//包含自己
            return ids;
        }

        public static IEnumerable<UserDept> GetSonList(IList<UserDept> list, int Pid)
        {
            var query = list.Where(p => p.Pid == Pid).ToList();
            return query.ToList().Concat(query.ToList().SelectMany(t => GetSonList(list, t.Id)));
        }
        #endregion

        #region 获取所有上级
        public static IEnumerable<UserDept> GetFatherList(IList<UserDept> list, int Id)
        {
            var query = list.Where(p => p.Id == Id).ToList();
            return query.ToList().Concat(query.ToList().SelectMany(t => GetFatherList(list, t.Pid)));
        }
        #endregion

        public async Task<object> InsertAsync(EditUserDept adminUserDept)
        {
            _cacheManager.Remove(cacheKey);
            UserDept userDept = new()
            {
                Pid = adminUserDept.Pid,
                DeptName = adminUserDept.DeptName,
                OrderNum = adminUserDept.OrderNum,
                Remark = adminUserDept.Remark
            };
            return await _adminUserDept.InsertAsync(userDept);
        }

        public async Task<int> UpdateAsync(UserDept adminUserDept)
        {
            _cacheManager.Remove(cacheKey);
            return await _adminUserDept.UpdateAsync(adminUserDept);
        }
        public async Task<int> UpdateUserDeptCateRoleAsync(UserDeptCateRole adminUserDeptCate)
        {
            UserDept adminUserDept = await GetInfo(adminUserDeptCate.Id);

            if (adminUserDeptCate.ContentCateRole != null)
                adminUserDept.ContentCateRole = adminUserDeptCate.ContentCateRole;

            if (0 < await _adminUserDept.UpdateAsync(adminUserDept))
            {
                _cacheManager.Remove(cacheKey);
                return 1;
            }
            return 0;
        }
        public async Task<int> DeleteByPriKeyAsync(int id)
        {
            if (await _adminUser.GetUserByDeptIdAsync(id))
                return -1;
            _cacheManager.Remove(cacheKey);
            return await _adminUserDept.DeleteByPriKeyAsync(id);
        }


        public async Task<IEnumerable<ViewUserDept>> GetUserDeptListAsync()
        {
            List<UserDept> cates = await GetAllAsync();
            return cates.AsCateListItems();//导出带 所有栏目封装数据
        }


        /// <summary>
        /// 输出JSON 树形栏目列表 内容管理的菜单列表使用
        /// </summary>
        /// <returns></returns>

        public async Task<IEnumerable<ViewUserDept>> AsUserDeptTree()
        {
            var all = await GetAllAsync();
            List<ViewUserDept> treeModels = new();
            UserDeptExtensions.IndentedCate(all, treeModels);
            return treeModels;
        }

        /// <summary>
        /// 列表
        /// </summary>
        /// <returns></returns>
        public async Task<IEnumerable<ViewUserDept>> GetUserDepts()
        {
            return await GetUserDepts(0, await GetAllAsync());
        }


        /// <summary>
        /// 递归栏目树
        /// </summary>
        /// <returns></returns>
        private async Task<List<ViewUserDept>> GetUserDepts(int pid, List<UserDept> depts = null)
        {
            var parent = depts.Where(P => P.Pid == pid);
            List<ViewUserDept> lists = new();
            foreach (var item in parent)
            {
                ViewUserDept Childer = new()
                {
                    Id = item.Id,
                    DeptName = item.DeptName,
                    OrderNum = item.OrderNum,
                    Remark = item.Remark,
                    GreatTime = item.GreatTime,
                };
                Childer.Children = await GetSon(Childer, depts);
                if (Childer.Children != null)
                {
                    Childer.HaveChild = true;
                    Childer.Open = true;
                }
                lists.Add(Childer);
            }
            async Task<List<ViewUserDept>> GetSon(ViewUserDept cates, List<UserDept> sonCates = null)
            {
                if (!sonCates.Exists(x => x.Pid == cates.Id))
                {
                    return null;
                }
                else
                {
                    return await GetUserDepts(cates.Id, sonCates);
                }
            }
            return lists.OrderBy(o => o.OrderNum).ThenBy(o => o.Id).ToList();
        }
    }
}
